using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Entity : MonoBehaviour
{
    [Header("碰撞信息 Collision info")]//碰撞信息
    [Tooltip("检测攻击碰撞的实体")]
    public Transform attackCheck;
    [Tooltip("攻击范围半径")]
    public float attackCheckRadius;
    [Tooltip("检测地面距离的实体")]
    [SerializeField] protected Transform groundCheck;
    [Tooltip("距离地面高度")]
    [SerializeField] protected float groundCheckDistance;//中心点距离地面层距离
    [Tooltip("地面层")]
    [SerializeField] protected LayerMask whatIsGround;//地面层
    [Space]
    [Tooltip("检测墙面实体")]
    [SerializeField] protected Transform wallCheck;
    [Tooltip("到墙面的距离")]
    [SerializeField] protected float wallCheckDistance;

    [Header("被击退信息 Knoclback info")]
    [Tooltip("击退位移")]
    [SerializeField] protected Vector2 knockbackDirection;
    [Tooltip("击退时间")]
    [SerializeField] protected float knockbackDuration;
    protected bool isKnocked;//击退状态

    public System.Action onFlipped;//翻转事件


    #region Components 组件

    public Animator anim { get; private set; }//动画组件
    public Rigidbody2D rb { get; private set; }//刚体组件
    public EntityFX fx { get; private set; }//Fx脚本
    public SpriteRenderer sr { get; private set; }//精灵组件
    public CharacterStats stats { get; private set; }//统计脚本组件
    public CapsuleCollider2D cd { get; private set; }//碰撞体组件

    #endregion
    //人物朝向
    public int facingDir { get; private set; } = 1;
    protected bool facingRight { get; private set; } = true;

    public int konkcbackDir { get; private set; }

    protected virtual void Awake()
    {

    }

    protected virtual void Start()
    {
        anim = GetComponentInChildren<Animator>();//获取动画组件
        sr = GetComponentInChildren<SpriteRenderer>();//获取精灵组件
        fx = GetComponent<EntityFX>();//获取Fx脚本组件
        rb = GetComponent<Rigidbody2D>();//获取刚体组件
        stats = GetComponent<CharacterStats>();//获取统计脚本组件
        cd = GetComponent<CapsuleCollider2D>();//获取碰撞体组件
    }

    protected virtual void Update()
    {

    }

    public virtual void Die()
    {

    }
    #region 寒冷状态
    //减速倍率和时间
    public virtual void SlowEntityBy(float _slowPercentage, float _slowDuration)
    {

    }
    //变回正常
    protected virtual void ReturnDefaultSpeed()
    {
        anim.speed = 1;
    }
    #endregion

    #region Hit
    // 受到攻击击退
    public virtual void DamageImpact()
    {
        StartCoroutine("HitKnockback");//击退
    }

    // 根据伤害来源设置被击退的方向
    public virtual void SetupKnockbackDir(Transform _danageDirection)
    {
        if (_danageDirection.position.x > transform.position.x)
        {
            konkcbackDir = -1;
        }
        else if (_danageDirection.position.x < transform.position.x)
        {
            konkcbackDir = 1;
        }
    }

    //击退
    protected virtual IEnumerator HitKnockback()
    {
        isKnocked = true;
        rb.velocity = new Vector2(knockbackDirection.x * konkcbackDir, knockbackDirection.y);
        yield return new WaitForSeconds(knockbackDuration);
        isKnocked = false;
        // SetZeroVelocity();
        SetupZeroKnockbackPower();
    }

    public void SetupKnockbackPower(Vector2 _knockbackpower) => knockbackDirection = _knockbackpower;

    protected virtual void SetupZeroKnockbackPower()
    {

    }

    #endregion

    #region 碰撞 Collision
    // 与地面碰撞
    public virtual bool IsGroundDetected() => Physics2D.Raycast(groundCheck.position, Vector2.down, groundCheckDistance, whatIsGround);
    // 与墙碰撞
    public virtual bool IsWallDetected() => Physics2D.Raycast(wallCheck.position, Vector2.right * facingDir, wallCheckDistance, whatIsGround);

    // 画线辅助观察
    protected virtual void OnDrawGizmos()
    {
        //Gizmos.DrawLine(第一个点，第二个点)
        // groundCheck到地面，用来检测人物是否站在地面
        Gizmos.color = Color.red;
        Gizmos.DrawLine(groundCheck.position, new Vector3(groundCheck.position.x, groundCheck.position.y - groundCheckDistance));
        // wallCheck到墙面，用来检测人物是否接触墙面
        Gizmos.color = Color.blue;
        Gizmos.DrawLine(wallCheck.position, new Vector3(wallCheck.position.x + wallCheckDistance * facingDir, wallCheck.position.y));
        //画出圆形攻击范围
        Gizmos.DrawWireSphere(attackCheck.position, attackCheckRadius);
    }

    #endregion

    #region 翻转 Flip
    // 人物翻转
    public virtual void Flip()
    {
        facingDir = facingDir * -1;
        facingRight = !facingRight;
        transform.Rotate(0, 180, 0);
        if (onFlipped != null)//翻转事件没有被订阅
        { onFlipped(); }
    }

    // 控制人物翻转
    public virtual void FlipController(float _x)
    {
        if (_x > 0 && !facingRight)//向右且脸朝左，facingDir应该能代替facingRight
        {
            Flip();
        }
        else if (_x < 0 && facingRight)//向左且脸朝右
        {
            Flip();
        }
    }
    #endregion

    #region 刚体速度 Velocity
    //静止角色
    public void SetZeroVelocity()
    {
        if (isKnocked) return;

        rb.velocity = new Vector2(0, 0);


    }

    // 左右移动（可转脸）
    public void SetVelocity(float _xVelocity, float _yVelocity)
    {
        if (isKnocked) return;// 被击退不能动
        FlipController(_xVelocity);
        rb.velocity = new Vector2(_xVelocity, _yVelocity);
    }

    #endregion

}
